package com.infocollect.project.api.helper;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class MapHelper {
    /**
     * 判断对象或对象数组中每一个对象是否为空: 对象为null，字符序列长度为0，集合类、Map为empty
     *
     * @param obj
     * @return
     */
    private static  boolean isNullOrEmpty(Object obj) {
        if (obj == null)
            return true;

        if (obj instanceof CharSequence)
            return ((CharSequence) obj).length() == 0;

        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();

        if (obj instanceof Map)
            return ((Map) obj).isEmpty();

        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {
                return true;
            }
            boolean empty = true;
            for (int i = 0; i < object.length; i++) {
                if (!isNullOrEmpty(object[i])) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }

        return false;
    }
    public static Object convertMap2Obj(Map<String, String> map, Class clazz) throws InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException, IllegalArgumentException,ParseException{
        if(isNullOrEmpty(map)){
            return null;
        }
        Object obj=clazz.newInstance();
        setObjectValue(obj, map);
        return obj;
    }
    /***
     * 利用反射设置对象的属性值. 注意:属性可以没有setter 方法.
     *
     * @param obj
     * @param params
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void setObjectValue(Object obj, Map<String, String> params)
            throws SecurityException,
            IllegalArgumentException, IllegalAccessException, NoSuchFieldException,ParseException {
        if(isNullOrEmpty(obj)){
            return;
        }
        if (isNullOrEmpty(params)) {
            return;
        }
        Class<?> clazz = obj.getClass();
        for (Iterator it = params.entrySet().iterator(); it.hasNext();) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) it
                    .next();
            String key = entry.getKey();
            String propertyValue = entry.getValue();
           // System.out.println("字段"+key+"值"+propertyValue);
            if (isNullOrEmpty(propertyValue)) {
                continue;
            }
            Field name = getSpecifiedField(clazz, key);
         //   System.out.println("字段"+name);
            SetFieldValue(obj,name,propertyValue);
        }

    }
    /***
     * Get Specified Field
     *
     * @param clazz
     * @param fieldName
     * @return
     */
    public static Field getSpecifiedField(Class<?> clazz, String fieldName) {

            Field f = null;
            if (isNullOrEmpty(clazz)) {
                return null;
            }
            String newfieldName =fieldName.toLowerCase();//fieldName.substring(0, 1).toUpperCase()+  fieldName.substring(1, fieldName.length()).toLowerCase();
         //   System.out.println("新增字段名称："+newfieldName);
            try {
                f = clazz.getDeclaredField(newfieldName);
            } catch (NoSuchFieldException e) {
                return getSpecifiedField(clazz.getSuperclass()/*
                 * may be null if it is
                 * Object .
                 */, newfieldName);
                // e.printStackTrace();
            }
            return f;

    }
    static void SetFieldValue(Object obj,Field f,String propertyValue)  throws SecurityException,
            IllegalArgumentException, IllegalAccessException, NoSuchFieldException, ParseException {
        if (f != null) {
            String type = f.getGenericType().toString();
            f.setAccessible(true);
            if (type.equals("class java.lang.String")) {
                f.set(obj, propertyValue);
            } else if (type.equals("class java.util.Date")) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = dateFormat.parse(propertyValue);
                if (date != null) {
                    f.set(obj, date);
                }
            }  else if (type.equals("class java.lang.Integer")) {
                Integer value = Integer.parseInt(propertyValue);
                if (value != null) {
                    f.set(obj, value);
                }
            } else if (type.equals("class java.lang.Short")) {
                Short value = Short.parseShort(propertyValue);
                if (value != null) {
                    f.set(obj, value);
                }
            } else if (type.equals("class java.lang.Double")) {
                Double value = Double.parseDouble(propertyValue);
                if (value != null) {
                    f.set(obj, value);
                }
            } else if (type.equals("class java.lang.Float")) {
                Float value = Float.parseFloat(propertyValue);
                if (value != null) {
                    f.set(obj, value);
                }
            } else if (type.equals("class java.lang.Long")) {
                Long value = Long.parseLong(propertyValue);
                if (value != null) {
                    f.set(obj, value);
                }
            } else if (type.equals("class java.lang.Boolean")) {
                Boolean value = Boolean.parseBoolean(propertyValue);
                if (value != null) {
                    f.set(obj, value);
                }
            } else {
                f.set(obj, propertyValue);
            }

        }
    }
    /***
     * convert entity to Map
     * @param obj
     * @param excludeProperties
     * @param excludeZero : 是否过滤zero
     * @return
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static Map convertObj2Map(Object obj, String[] excludeProperties, boolean excludeZero) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Map map = new HashMap();
        List<Field> fieldsList = ReflectHelper.getAllFieldList(obj.getClass());
        for (int i = 0; i < fieldsList.size(); i++) {
            Field f = fieldsList.get(i);
            if (Arrays.binarySearch(excludeProperties, f.getName())==0) {
                continue;
            }
            Object propertyValue = ReflectHelper.getObjectValue(obj, f);
            if (excludeZero) {
                if (propertyValue instanceof Integer) {
                    int ii = (Integer) propertyValue;
                    if (ii == 0) {
                        continue;
                    }
                } else if (propertyValue instanceof Long) {
                    int ii = ((Long) propertyValue).intValue();
                    if (ii == 0) {
                        continue;
                    }
                }
            }
            if (!isNullOrEmpty(propertyValue)) {
                map.put(f.getName(), propertyValue);
            }
        }
        return map;
    }
}
